#pragma once
#include "mysql.hpp"
#include "message-odb.hxx"
#include "log.hpp"

#include <vector>
class MessageTable {
public:
    using ptr = std::shared_ptr<MessageTable>;
    MessageTable(const std::shared_ptr<odb::core::database> &db) : _db(db) {}

    bool insert(Message msg) {
        try {
            odb::transaction trans(_db->begin());
            _db->persist(msg);
            trans.commit();
        }
        catch (const odb::exception &e) {
            LOG_ERROR("插入消息失败: {}:{}", msg.content(), e.what());
            return false;
        }
        LOG_INFO("插入消息成功: {}:{}", msg.content(), msg.message_id());
        return true;
    }


    // 删除指定会话的所有消息
    bool remove(const std::string& session_id) {
        try {
            odb::transaction trans(_db->begin());
            using query_t = odb::query<Message>;
            _db->erase_query<Message>(query_t::session_id == session_id);
            trans.commit();
        }
        catch (const odb::exception &e) {
            LOG_ERROR("删除消息失败: {}:{}", session_id, e.what());
            return false;
        }
        LOG_INFO("删除消息成功: {}", session_id);
        return true;
    }



    // 获取指定会话的最近 count 条消息
    std::vector<Message> recent(const std::string& session_id, int count) {
        std::vector<Message> messages;
        try {
            odb::transaction trans(_db->begin());
            using query_t = odb::query<Message>;
            using result_t = odb::result<Message>;
            std::string condition = std::string("session_id=") + "\'" + session_id + "\'"
                                    + std::string(" order by create_time desc ") 
                                    + " limit " + std::to_string(count);
            result_t res = _db->query<Message>(condition);
            for (auto& msg : res) {
                messages.push_back(msg);
            }
            trans.commit();
        }
        catch (const odb::exception &e) {
            LOG_ERROR("获取最近消息失败: {}:{}", session_id, e.what());
            return {};
        }
        LOG_INFO("获取最近消息成功: {} 条", messages.size());
        return messages;
    }


    // 获取指定会话某个时间段的消息
    std::vector<Message> range (const std::string& session_id, 
                                boost::posix_time::ptime start, 
                                boost::posix_time::ptime end) {
        std::vector<Message> messages;  
        start <= end;
        try {
            odb::transaction trans(_db->begin());
            using query_t = odb::query<Message>;
            using result_t = odb::result<Message>;
            result_t res = _db->query<Message>(query_t::create_time >= start && 
                                               query_t::create_time <= end && 
                                               query_t::session_id == session_id);
            for (auto& msg : res) {
                messages.push_back(msg);
            }
            trans.commit();
        }
        catch(const odb::exception &e) {
            LOG_ERROR("获取时间段消息失败: {}:{}", session_id, e.what());
            return {};
        }
        LOG_INFO("获取时间段消息成功: {} 条", messages.size());
        return messages;
    }
private:
    std::shared_ptr<odb::core::database> _db;
};